var socket = null;//实例对象
var lockReconnect = false; //是否真正建立连接
var timeout = 5 * 1000; //20秒一次心跳
var timeoutObj = null; //心跳倒计时
var serverTimeoutObj = null; //服务心跳倒计时
var timeoutnum = null; //断开 重连倒计时

const initWebSocket = async () => {
  if ("WebSocket" in window) {
    const wsUrl = 'ws://192.168.5.78:8888';
    socket = new WebSocket(wsUrl);
    socket.onerror = webSocketOnError;
    socket.onmessage = webSocketOnMessage;
    socket.onclose = closeWebsocket;
    socket.onopen = openWebsocket;
  } else {
    alert('您的浏览器不支持websocket，请更换Chrome或者Firefox')
  }
}

// 1.建立连接，并开启心跳
const openWebsocket = (e) => {
  console.log('1.Websoket connected.');
  start();
}

// 开启心跳
const start = () => {
  //开启心跳
  timeoutObj && clearTimeout(timeoutObj);
  serverTimeoutObj && clearTimeout(serverTimeoutObj);
  timeoutObj = setTimeout(function () {
    console.log('socket.readyState:',socket.readyState);
    //这里发送一个心跳，后端收到后，返回一个心跳消息
    if (socket.readyState == 1) {
      console.log('socket:',socket);
      //如果连接正常
      socket.send("heartbeat");
    } else {
      //否则重连
      reconnect();
    }
    serverTimeoutObj = setTimeout(function () {
      //超时关闭
      socket.close();
    }, timeout);
  }, timeout);
}

//重新连接
const reconnect = () => {
  if (lockReconnect) {
    return;
  }
  lockReconnect = true;
  //没连接上会一直重连，设置延迟避免请求过多
  timeoutnum && clearTimeout(timeoutnum);
  timeoutnum = setTimeout(function () {
    //新连接
    initWebSocket();
    lockReconnect = false;
  }, 1000);
}

//重置心跳
const reset = () => {
  //清除时间
  clearTimeout(timeoutObj);
  clearTimeout(serverTimeoutObj);
  //重启心跳
  start();
}

const sendWebsocket = (e) => {
  // socket.send(`我发消息了`);
}

const webSocketOnError = (e) => {
  initWebSocket();
  reconnect();

}

//服务器返回的数据
const webSocketOnMessage = (e) => {
  //判断是否登录
  //window自定义事件[下面有说明]
  window.dispatchEvent(
    new CustomEvent("onmessageWS", {
      detail: {
        data: JSON.parse(e?.data),
      },
    })
  );
  reset();
}

const closeWebsocket = (e) => {
  reconnect();
}

//断开连接
const close = () => {
  //WebSocket对象也有发送和关闭的两个方法，只需要在自定义方法中分别调用send()和close()即可实现。
  socket.close();
  socket.send('close')
}
//具体问题具体分析,把需要用到的方法暴露出去
export default { initWebSocket, sendWebsocket, webSocketOnMessage, close };